using System;
using System.Collections.Generic;
using System.Text;
using org.apache.mina.common;
using org.apache.mina.transport.socket.nio;

namespace PDSClient.Utils.IO.Impl
{
    class SocketConnection : java.lang.Object, IConnection, IFilterListener
    {
        private IConnectionListener listener;

        private CompleteMessageFilter filter;

        private IoSession session;

        public SocketConnection(IConnectionListener listener, CompleteMessageFilter filter, IoSession session)
        {
            if (listener == null || filter == null || session == null)
                throw new ArgumentNullException("null argument to constructor");

            this.listener = listener;
            this.filter = filter;
            this.session = session;

            if (session.getTransportType() == org.apache.mina.common.TransportType.SOCKET)
            {
                SocketSessionConfig cfg = (SocketSessionConfig)session.getConfig();
                cfg.setTcpNoDelay(true);
            }
        }

        public void SendBytes(byte[] message)
        {
            if (!session.isConnected())
            {
                Exception e = new Exception("SocketConnection.sendBytes: session not connected");
                //logging logger.logThrow(Level.FINE, e, e.Message);
                throw e;
            }

            //the filter does the actual work to prepend the length
            filter.FilterSend(this, message);
        }

        public void Close()
        {
            //logger logger.log(Level.FINER, "session = {0}", session);
            if (!session.isConnected())
            {
                Exception e = new Exception("SocketConnection.close: session not connected");
                //logging logger.logThrow(Level.FINE, ioe, ioe.getMessage());
                throw e;
            }
            session.close();
        }

        public void FilteredMessageReceived(ByteBuffer buf)
        {
            byte[] message = new byte[buf.remaining()];
            buf.get(message);
            listener.BytesReceived(this, message);
        }

        public void SendUnfilteredMessage(ByteBuffer buf)
        {
            //logging logger.log(Level.FINEST, "message = {0}", buf);
            session.write(buf);
        }

        public IConnectionListener ConnectionListener { get { return listener; } }

        public CompleteMessageFilter Filter { get { return filter; } }
    }
}
